package org.vison.framework.doc.web;

import java.lang.reflect.*;
import java.net.URI;
import java.net.URL;
import java.util.*;

import org.vison.framework.doc.annotation.ApiProperty;
import org.vison.framework.doc.web.ApiInfo.ApiModel;
import org.vison.framework.doc.web.ApiInfo.ApiParam;
import org.vison.framework.doc.FieldTypeUtils;

public class TypeFieldResolver {


    // 解析参数类型的所有字段
    // 支持普通类型、参数化类型、多层嵌套参数化类型
    public static ApiModel resolveParameterTypeFields(Parameter parameter) {
        ApiModel apiModel = new ApiModel();
        List<ApiParam> params = new ArrayList<>();
        Type type = parameter.getParameterizedType();
        FieldTypeUtils.TypeInfo typeInfo = FieldTypeUtils.getTypeInfo(type);
        apiModel.setType(typeInfo.getQualifiedName());
        resolveType(type, new HashMap<>(), params);
        apiModel.addParams(params);
        return apiModel;
    }
    
    /**
     * 解析方法返回类型的所有字段
     * 支持普通类型、参数化类型、多层嵌套参数化类型
     */
    public static ApiModel resolveMethodReturnTypeFields(Method method) {
        ApiModel apiModel = new ApiModel();
        List<ApiParam> params = new ArrayList<>();
        
        // 获取方法返回类型
        Type returnType = method.getGenericReturnType();
        
        // 使用 FieldTypeUtils 获取类型信息并设置到 ApiModel
        FieldTypeUtils.TypeInfo typeInfo = FieldTypeUtils.getTypeInfo(returnType);
        apiModel.setType(typeInfo.getQualifiedName());
//        Map<String, Type> typeVarMap = getVarMap(returnType);
        // 创建泛型参数映射

        // 解析返回类型的字段
        resolveType(returnType,new HashMap<>(), params);
        
        // 添加到ApiModel
        apiModel.addParams(params);
        
        return apiModel;
    }

    private static Map<String, Type> getVarMap(Type returnType) {
        Map<String, Type> typeVarMap = new HashMap<>();
        if(returnType instanceof ParameterizedType){
            ParameterizedType parameterizedType = (ParameterizedType) returnType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            for (int i = 0; i < actualTypeArguments.length; i++) {
                Type genericParameterType = actualTypeArguments[i];
                if (genericParameterType instanceof ParameterizedType) {
                    Type rawType = parameterizedType.getRawType();
                    if (rawType instanceof Class) {
                        Class<?> rawClass = (Class<?>) rawType;
                        typeVarMap.put(rawClass.getSimpleName(), parameterizedType);
                    }
                }
            }
        }
        return typeVarMap;
    }

    private static ApiInfo.ApiParam resolveFieldToApiParameter(Field field) {
        field.setAccessible(true);
        ApiInfo.ApiParam fieldInfo = new ApiInfo.ApiParam();
        fieldInfo.setName(field.getName());
        fieldInfo.setFullType(field.getType().getName());
        FieldTypeUtils.TypeInfo typeInfo = FieldTypeUtils.getFieldTypeInfo(field);
        fieldInfo.setSimpleType(typeInfo.getSimpleName());

        // 检查ApiProperty注解
        if (field.isAnnotationPresent(ApiProperty.class)) {
            ApiProperty apiProperty = field.getAnnotation(ApiProperty.class);
            fieldInfo.setDescription(apiProperty.description());
            fieldInfo.setRequired(apiProperty.required());
            fieldInfo.setVersion(apiProperty.version());
            fieldInfo.setDefaultValue(apiProperty.defaultValue());
            fieldInfo.setExample(apiProperty.example());
            fieldInfo.setOrder(apiProperty.order());
        }
        return fieldInfo;
    }
    
    /**
     * 递归解析类型及其字段
     * @param type 当前要解析的类型
     * @param typeVarMap 泛型参数映射
     * @param parentParams 存储解析结果的父列表
     */
    private static void resolveType(Type type, Map<String, Type> typeVarMap, List<ApiParam> parentParams) {
        // 判断类型是否为简单类型
        // 如果是简单类型，不需要继续递归解析
        if (type instanceof Class && isSimpleType((Class<?>) type)) {
            return;
        }
        
        try {
            if (type instanceof Class) {
                Class<?> clazz = (Class<?>) type;
                resolveClassFields(clazz, typeVarMap, parentParams);
            } else if (type instanceof ParameterizedType) {
                ParameterizedType paramType = (ParameterizedType) type;
                Type rawType = paramType.getRawType();
                
                if (rawType instanceof Class) {
                    Class<?> rawClazz = (Class<?>) rawType;
                    Type[] actualTypes = paramType.getActualTypeArguments();

                    // 对于集合类型，检查元素类型是否为简单类型
                    if (Collection.class.isAssignableFrom(rawClazz) && actualTypes.length > 0) {
                        // 如果集合元素是简单类型，不需要添加嵌套字段
                        if (actualTypes[0] instanceof Class && isSimpleType((Class<?>) actualTypes[0])) {
                            return;
                        }
                        
                        // 对于复杂集合类型，我们需要递归解析元素类型
                        // 直接将元素类型的字段添加到父参数列表
                        resolveType(actualTypes[0], typeVarMap, parentParams);
                        return;
                    } 
                    // 对于Map类型，检查键值类型是否都为简单类型
                    else if (Map.class.isAssignableFrom(rawClazz) && actualTypes.length > 1) {
                        // 如果键和值都是简单类型，不需要添加嵌套字段
                        if ((actualTypes[0] instanceof Class && isSimpleType((Class<?>) actualTypes[0])) &&
                            (actualTypes[1] instanceof Class && isSimpleType((Class<?>) actualTypes[1]))) {
                            return;
                        }
                        
                        // 对于复杂Map类型，我们需要递归解析值类型
                        resolveType(actualTypes[1], typeVarMap, parentParams);
                        return;
                    }
                    
                    // 创建新的泛型参数映射，基于当前的映射
                    Map<String, Type> newTypeVarMap = new HashMap<>(typeVarMap);
                    
                    // 获取类的类型变量和实际类型参数
                    Type[] typeVars = rawClazz.getTypeParameters();
                    
                    // 更新泛型参数映射
                    for (int i = 0; i < Math.min(typeVars.length, actualTypes.length); i++) {
                        String varName = typeVars[i].getTypeName();
                        newTypeVarMap.put(varName, actualTypes[i]);
                    }
                    
                    // 解析原始类型的字段
                    resolveClassFields(rawClazz, newTypeVarMap, parentParams);
                }
            }
        } catch (Exception e) {
            // 捕获可能的 MalformedParameterizedTypeException 或其他类型解析异常
            // 记录错误但继续执行，避免整个解析过程失败
        }
    }
    
    /**
     * 解析类的所有字段
     */
    private static void resolveClassFields(Class<?> clazz, Map<String, Type> typeVarMap, List<ApiParam> params) {
        // 跳过简单类型
        if (isSimpleType(clazz)) {
            return;
        }
        
        // 处理继承关系，确保父类字段也被解析
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null && !superClass.equals(Object.class)) {
            resolveClassFields(superClass, typeVarMap, params);
        }
        
        // 获取类的所有字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            // 跳过static、final和transient字段
            if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) || 
                java.lang.reflect.Modifier.isFinal(field.getModifiers()) || 
                java.lang.reflect.Modifier.isTransient(field.getModifiers())) {
                continue;
            }
            
            field.setAccessible(true);
            
            // 创建ApiParam对象
            ApiParam param = new ApiParam();
            param.setName(field.getName());
            
            // 初始化nestedFields列表，确保非空
            param.setNestedFields(new ArrayList<>());
            
            // 使用FieldTypeUtils获取更准确的类型信息
            Type fieldType = field.getGenericType();
            
            // 解析字段类型，处理泛型参数替换
            Type resolvedType = resolveFieldType(fieldType, typeVarMap);
            
            // 获取字段类型信息
            FieldTypeUtils.TypeInfo typeInfo;
            if (typeVarMap != null && !typeVarMap.isEmpty()) {
                // 获取类的泛型参数
                TypeVariable<? extends Class<?>>[] typeVars = clazz.getTypeParameters();
                Type[] actualTypeArgs = new Type[typeVars.length];
                for (int i = 0; i < typeVars.length; i++) {
                    actualTypeArgs[i] = typeVarMap.getOrDefault(typeVars[i].getName(), typeVars[i]);
                }
                
                // 使用FieldTypeUtils获取字段类型信息
                typeInfo = FieldTypeUtils.getFieldTypeInfo(field, actualTypeArgs);
            } else {
                // 直接使用FieldTypeUtils获取字段类型信息
                typeInfo = FieldTypeUtils.getFieldTypeInfo(field);
            }
            param = resolveFieldToApiParameter(field);
            param.setFullType(typeInfo.getQualifiedName());
            param.setSimpleType(typeInfo.getSimpleName());
            // 递归解析嵌套字段
            resolveType(resolvedType, typeVarMap, param.getNestedFields());
            
            params.add(param);
        }
    }
    
    /**
     * 解析字段类型，替换泛型变量为实际类型
     */
    private static Type resolveFieldType(Type fieldType, Map<String, Type> typeVarMap) {
        // 如果是泛型变量（如T），尝试替换为实际类型
        if (fieldType instanceof ParameterizedType) {
            ParameterizedType paramType = (ParameterizedType) fieldType;
            Type rawType = paramType.getRawType();
            
            // 对于参数化类型，递归替换其类型参数
            if (rawType instanceof Class) {
                Type[] actualTypes = paramType.getActualTypeArguments();
                Type[] resolvedTypes = new Type[actualTypes.length];
                
                for (int i = 0; i < actualTypes.length; i++) {
                    resolvedTypes[i] = resolveFieldType(actualTypes[i], typeVarMap);
                }
                
                // 创建新的ParameterizedType，保持原始类型结构
                return new ParameterizedType() {
                    @Override
                    public Type[] getActualTypeArguments() {
                        return resolvedTypes;
                    }
                    
                    @Override
                    public Type getRawType() {
                        return rawType;
                    }
                    
                    @Override
                    public Type getOwnerType() {
                        return paramType.getOwnerType();
                    }
                };
            }
            
            return paramType;
        }
        
        // 如果是泛型变量名（如T），尝试在映射中查找
        String typeName = fieldType.getTypeName();
        if (typeVarMap.containsKey(typeName)) {
            return typeVarMap.get(typeName);
        }
        
        return fieldType;
    }
    
    /**
     * 判断是否为简单类型，简单类型不需要进一步解析
     */
    private static boolean isSimpleType(Class<?> clazz) {
        // 基本类型和基本类型的包装类
        if (clazz.isPrimitive() || 
            clazz.equals(Integer.class) ||
            clazz.equals(Long.class) ||
            clazz.equals(Double.class) ||
            clazz.equals(Float.class) ||
            clazz.equals(Boolean.class) ||
            clazz.equals(Character.class) ||
            clazz.equals(Byte.class) ||
            clazz.equals(Short.class) ||
            // 常见的简单引用类型
            clazz.equals(String.class) ||
            clazz.equals(Enum.class) ||
            clazz.equals(Date.class) ||
            clazz.equals(java.sql.Date.class) ||
            clazz.equals(java.sql.Time.class) ||
            clazz.equals(java.sql.Timestamp.class) ||
            clazz.equals(Class.class) ||
            clazz.equals(URI.class) ||
            clazz.equals(URL.class) ||
            clazz.isEnum()) {
            return true;
        }
        return false;
    }
}